#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <gmssl/sm2.h>  
#include <gmssl/sm3.h>  
#include <gmssl/error.h>  
void print_hex(const char *label, const uint8_t *data, size_t len) {  
	    printf("%s: ", label);  
	        for(size_t i = 0; i < len; i++) {  
			        printf("%02X", data[i]);  
				    }  
		    printf("\n");  
}  

int main() {  
	    int ret = 0;  

	        SM2_KEY key;  
		    
		    printf("生成 SM2 密钥?..\n");  
		        ret = sm2_key_generate(&key);  
			    if (ret != 1) {  
				            fprintf(stderr, "SM2 密钥生成失败\n");  
					            return EXIT_FAILURE;  
						        }  
			        printf("SM2 密钥生成成功n");  

				    const char *plaintext = "Hello, SM2!";  
				        size_t plaintext_len = strlen(plaintext);  
					    printf("明文: %s\n", plaintext);  

					        uint8_t ciphertext[SM2_MAX_CIPHERTEXT_SIZE];  
						    size_t ciphertext_len = sizeof(ciphertext);  

						        printf("加密明文...\n");  
							    ret = sm2_encrypt(&key, (const uint8_t *)plaintext, plaintext_len, ciphertext, &ciphertext_len);  
							        if (ret != 1) {  
									        fprintf(stderr, "SM2 加密失败\n");  
										        return EXIT_FAILURE;  
											    }  
								    printf("加密成功。\n");  

								        print_hex("密文", ciphertext, ciphertext_len);  

									    uint8_t decrypted[SM2_MAX_PLAINTEXT_SIZE];  
									        size_t decrypted_len = sizeof(decrypted);  

										    printf("解密密文...\n");  
										        ret = sm2_decrypt(&key, ciphertext, ciphertext_len, decrypted, &decrypted_len);  
											    if (ret != 1) {  
												            fprintf(stderr, "SM2 解密失败\n");  
													            return EXIT_FAILURE;  
														        }  
											        printf("解密成功。\n");  

												    decrypted[decrypted_len] = '\0'; // 娣诲姞瀛楃涓茬粓姝㈢  
												        printf("解密后的明文: %s\n", decrypted);  

													    const char *message = "This is a message to be signed.";  
													        size_t message_len = strlen(message);  
														    printf("要签名的消息: %s\n", message);  
														      
														        SM2_SIGN_CTX sign_ctx;  
															    sm2_sign_init(&sign_ctx, &key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);  

															        ret = sm2_sign_update(&sign_ctx, (const uint8_t *)message, message_len);  
																    if (ret != 1) {  
																	            fprintf(stderr, "SM2 签名更新失败\n");  
																		            return EXIT_FAILURE;  
																			        }  

																        uint8_t signature[SM2_MAX_SIGNATURE_SIZE];  
																	    size_t signature_len = sizeof(signature);  
																	        ret = sm2_sign_finish(&sign_ctx, signature, &signature_len);  
																		    if (ret != 1) {  
																			            fprintf(stderr, "SM2 签名失败\n");  
																				            return EXIT_FAILURE;  
																					        }  
																		        printf("签名成功。\n");  

																			    print_hex("签名", signature, signature_len);  

																			        SM2_VERIFY_CTX verify_ctx;
																					sm2_verify_init(&verify_ctx, &key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);  

																					ret = sm2_verify_update(&verify_ctx, (const uint8_t *)message, message_len);
																					if (ret != 1) {
																						    fprintf(stderr, "SM2 签名验证更新失败\n");
																						        return EXIT_FAILURE;
																					}

																					ret = sm2_verify_finish(&verify_ctx, signature, signature_len);
																					if (ret == 1) {
																						    printf("签名验证成功。\n");
																					} else {
																						    printf("签名验证失败。\n");
																						        return EXIT_FAILURE;
																					}

																					    return EXIT_SUCCESS;  
}
